/**
 * \file Interrupt.h
 * \brief Interrupt management facilities
 * \author Corey Tabaka
 */

/*
   Copyright 2006 Corey Tabaka

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include <ktypes.h>

#ifndef __KERNEL_INTERRUPT_H__
#define __KERNEL_INTERRUPT_H__

// needs to be NUM_INT-1 (NUM_INT defined in pm_system.asm)
#define INTERRUPT_MAX		0x34

// defined interrupts
#define INT_BASE			0x20
#define INT_PIT				0x20
#define INT_KEYBOARD		0x21
#define INT_PIC2			0x22

#define INT_BASE2			0x28
#define INT_CMOSRTC			0x28
#define INT_PS2MOUSE		0x2c
#define INT_IDE0			0x2e
#define INT_IDE1			0x2f

// exceptions
#define INT_DIVIDE_0		0x00
#define INT_DEBUG_EX		0x01
#define INT_INVALID_OP		0x06
#define INT_DEV_NA_EX		0x07

// faults
#define INT_STACK_FAULT		0x0c
#define INT_GP_FAULT		0x0d
#define INT_PAGE_FAULT		0x0e

// APIC vectors
#define INT_APIC_TIMER		0x22

#define INT_SYSCALL			0x30

typedef bool (*InterruptHandler)(regs_t *);

class Interrupt {
	protected:
	
	Interrupt(void);
	~Interrupt(void);
	
	public:
	
	static void initialize(void);
	
	static void registerHandler(uint8 interrupt, InterruptHandler handler,
		int priority = 0);
	static void unregisterHandler(uint8 interrupt, InterruptHandler handler);
	
	static void mask(uint8 interrupt);
	static void unmask(uint8 interrupt);
	
	static bool isHandled(uint8 interrupt);
	static void enableLocalInterrupts(void);
	static void disableLocalInterrupts(void);
	static void waitForInterrupt(void);
};

#endif
